﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace DeepZoomProject
{
    public partial class Page
    {
        protected MultiScaleImage MSI
        {
            get { return msi; }
        }

        private void InitializeInteraction()
        {
            this.MouseMove += new MouseEventHandler(InteractionMouseMove);

            var shuffleButton = new Button() { Height = 20, Width = 20, Content = "S" };
            shuffleButton.Click += new RoutedEventHandler(shuffleButton_Click);
            Canvas.SetLeft(shuffleButton, 317);
            Canvas.SetTop(shuffleButton, 4);

            buttonCanvas.Children.Add(shuffleButton);
        }

        void shuffleButton_Click(object sender, RoutedEventArgs e)
        {
            Shuffle();
        }

        private MultiScaleSubImage lastSubImage;
        private void InteractionMouseMove(object sender, MouseEventArgs e)
        {
            if (!duringDrag)
            {
                var subimage = GetSubImage(e.GetPosition(MSI));
                if (lastSubImage != subimage)
                {
                    lastSubImage = subimage;
                    if (subimage != null)
                    {
                        Storyboard sb = new Storyboard();
                        AnimateImageOver(sb, subimage);
                        sb.AutoReverse = true;
                        sb.Duration = new Duration(new TimeSpan(0, 0, 1));
                        sb.Begin();
                    }
                }
            }
        }

        private void AnimateImageOver(Storyboard sb, MultiScaleSubImage subimage)
        {
            PointAnimation animation = new PointAnimation();
            animation.To = new Point(subimage.ViewportOrigin.X, subimage.ViewportOrigin.Y + 0.2);
            animation.EasingFunction = new BounceEase { Bounces = 2, Bounciness = 8, EasingMode = EasingMode.EaseIn };
            Storyboard.SetTarget(animation, subimage);
            Storyboard.SetTargetProperty(animation, new PropertyPath("ViewportOrigin "));
            sb.Children.Add(animation);
        }


        private void Shuffle()
        {
            // Create a randomly ordered list of sub-image viewport origins
            List<Point> origins = new List<Point>();

            foreach (MultiScaleSubImage image in MSI.SubImages)
                origins.Add(image.ViewportOrigin);

            Random rand = new Random();
            int count = origins.Count;

            for (int i = 0; i < count; i++)
            {
                Point origin = origins[i];
                origins.RemoveAt(i);
                origins.Insert(rand.Next(count), origin);
            }

            // Create a Storyboard and animations for shuffling
            Storyboard sb = new Storyboard();

            for (int i = 0; i < count; i++)
            {
                PointAnimation animation = new PointAnimation();
                animation.Duration = TimeSpan.FromMilliseconds(250);
                animation.To = origins[i];
                Storyboard.SetTarget(animation, MSI.SubImages[i]);
                Storyboard.SetTargetProperty(animation,
                    new PropertyPath("ViewportOrigin "));
                sb.Children.Add(animation);
            }

            // Run the animations
            sb.Begin();
        }

        private MultiScaleSubImage GetSubImage(Point point)
        {
            // Hit-test each sub-image in the MultiScaleImage control to determine
            // whether  "point " lies within a sub-image
            for (int i = MSI.SubImages.Count - 1; i >= 0; i--)
            {
                MultiScaleSubImage image = MSI.SubImages[i];
                double width = MSI.ActualWidth /
                    (MSI.ViewportWidth * image.ViewportWidth);
                double height = MSI.ActualWidth /
                    (MSI.ViewportWidth * image.ViewportWidth * image.AspectRatio);

                Point pos = MSI.LogicalToElementPoint(new Point(
                    -image.ViewportOrigin.X / image.ViewportWidth,
                    -image.ViewportOrigin.Y / image.ViewportWidth)
                );
                Rect rect = new Rect(pos.X, pos.Y, width, height);

                if (rect.Contains(point))
                {
                    // Return the image index
                    return image;
                }
            }

            // No corresponding sub-image
            return null;
        }
    }
}
